<script setup lang='ts'>
import dayjs from 'dayjs'
import { useField } from 'vee-validate'

interface Props {
  modelValue?: string
  must?: boolean
  layout?: 'horizontal' | 'vertical'
  label?: string
}
defineOptions({
  name: 'BaseInputBirthday',
})
const props = withDefaults(defineProps<Props>(), {
  layout: 'vertical',
})
const emit = defineEmits(['update:modelValue'])
const { $i18n } = useNuxtApp()
const { t:$t } = $i18n
const dayInputRef = ref()
const yearInputRef = ref()
const showAllRed = ref(false)
const isPop = ref(false)

const monthList = [
  { label: 'time_january', value: 1 },
  { label: 'time_february', value: 2 },
  { label: 'time_march', value: 3 },
  { label: 'time_april', value: 4 },
  { label: 'time_may', value: 5 },
  { label: 'time_june', value: 6 },
  { label: 'time_july', value: 7 },
  { label: 'time_august', value: 8 },
  { label: 'time_september', value: 9 },
  { label: 'time_october', value: 10 },
  { label: 'time_november', value: 11 },
  { label: 'time_december', value: 12 },
]
const {
  value: month, setValue: setMonth,
  errorMessage: errorMonthMsg,
  validate: valiMonth,
  resetField: resetMonthField,
} = useField<number>('month', (value) => {
  showAllRed.value = false
  if (!value)
    return $t('surveys_birthday_error')

  return ''
}, { initialValue: 0,validateOnValueUpdate:false })
const {
  value: year,
  setValue: setYear,
  errorMessage: errorYearMsg,
  validate: valiYear,
  resetField: resetYearField,
} = useField<number>('year', (value) => {
  showAllRed.value = false
  if (!value)
    return $t('surveys_birthday_error')
  if (value < 1900)
    return $t('surveys_birthday_error')

  return ''
},{validateOnValueUpdate:false})

const dayMax = computed(() => {
  const have31 = [1, 3, 5, 7, 8, 10, 12]
  const have30 = [4, 6, 9, 11]

  if (month.value) {
    if (have31.includes(month.value))
      return 31

    if (have30.includes(month.value))
      return 30

    if (month.value === 2)
      return year.value && dayjs(`${year.value}-01-01`).isLeapYear() ? 29 : 28
  }

  return 31
})
const {
  value: day,
  setValue: setDay,
  errorMessage: errorDayMsg,
  validate: valiDay,
  resetField: resetDay,
} = useField<number>('day', (value) => {
  showAllRed.value = false
  if (!value)
    return $t('surveys_birthday_error')
  if (value > dayMax.value)
    return $t('day_no_max', { delta: dayMax.value })
  if (!(month.value >= 1 && month.value <= 12))
    resetMonthField()
  if (!year.value)
    resetYearField()

  return ''
},{validateOnValueUpdate:false})

if (props.modelValue) {
  const temp = props.modelValue.split('-')
  setYear(+temp[0])
  setMonth(+temp[1])
  setDay(+temp[2])
}

const curYear = dayjs().year()
const curMonth = dayjs().month() + 1
const curDay = dayjs().date()
const isOver120 = computed(() => {
  if (+year.value > 0 && +day.value > 0
    && +day.value <= +dayMax.value && +month.value > 0) {
    if (curYear - year.value >= 120) {
      if (curYear - year.value > 120) {
        return true
      }
      else {
        if (curMonth >= month.value) {
          if (curMonth > month.value) {
            return true
          }
          else {
            if (curDay > day.value)
              return true
            else return false
          }
        }
        else {
          return false
        }
      }
    }
    return false
  }
  return undefined
})

// 是否满足18岁
const isEnough = computed(() => {
  const yearStr = year.value ? year.value : ''
  const monthStr = month.value ? `-${month.value}` : ''
  const dayStr = day.value ? `-${day.value}` : ''

  if (year.value && +year.value >= 1900 && !errorDayMsg.value && !errorMonthMsg.value) {
    const birthDayjs = dayjs(month.value ? yearStr + monthStr + dayStr : yearStr)
    const currentDate = dayjs()
    const age = currentDate.diff(birthDayjs, 'year')

    if (month.value && age === 18) {
      const birthMonth = birthDayjs.month()
      const currentMonth = currentDate.month()

      if (day.value && currentMonth === birthMonth) {
        const birthDay = birthDayjs.date()
        const currentDay = currentDate.date()

        return currentDay >= birthDay
      }

      if (currentMonth >= birthMonth)
        return true
    }
    return month.value ? age > 18 : age >= 18
  }
  return false
})

const msg = computed(() => {
  if (day.value > dayMax.value)
    return $t('day_no_max', { delta: dayMax.value })
  if (!day.value || !month.value || !year.value)
    return $t('surveys_birthday_error')
  if (isOver120.value === true)
    return $t('max_age_around', { delta: 120 })
  if (!isEnough.value)
    return $t('you_have_to_enough_18')

  return errorDayMsg.value || errorMonthMsg.value || errorYearMsg.value
})

const isValid = computed(() => {
  return !!(!isOver120.value && isEnough.value && +month.value >= 1
    && +month.value <= 12
    && +day.value > 0 && +day.value <= +dayMax.value && +year.value >= 1900)
})

function onInput() {
  // if (day.value > 0 && day.value <= dayMax.value)
  //   checkValidTip(dayInputRef.value, '')

  // if (year.value >= 1900)
  //   checkValidTip(yearInputRef.value, '')

  setTimeout(() => {
    if (year.value && month.value && day.value && !msg.value) {
      emit('update:modelValue', `${year.value}-${month.value > 9
        ? month.value
        : `0${month.value}`}-${day.value > 9
          ? day.value
          : `0${day.value}`}`)
    }
  }, 0)
}
async function valiBirthday() {
  await valiMonth()
  await valiYear()
  await valiDay()
  //注释掉的这些是能够触发input的原生提示，有需要再放开
  // if (+day.value <= 0)
  //   checkValidTip(dayInputRef.value, $t('max_value', { delta: 1 }))

  // else if (+year.value < 1900)
  //   checkValidTip(yearInputRef.value, $t('max_value', { delta: 1900 }))

  // if (!isValid.value)
  //   showAllRed.value = true

  return msg.value
}

// function checkValidTip(el: HTMLObjectElement, msg: string) {
//   el?.checkValidity()
//   el?.setCustomValidity(msg) // 如果是 '', 会提示原生的校验提示
//   el?.reportValidity()
// }
function resetBirthday() {
  resetMonthField()
  resetYearField()
  resetDay()
  emit('update:modelValue', '')
}
function setAreaList(){
  return monthList.map(i=>{
    return{
      label: $t(`${i.label}`),
      value: i.value
    }
  })
}
onMounted(() => {
  if (props.modelValue) {
    const arr = props.modelValue.split('-')
    setYear(+arr[0])
    setMonth(+arr[1])
    setDay(+arr[2])
  }
})
watch(()=>month.value,()=>{
  onInput()
})
defineExpose({ valiBirthday, msg, isValid, resetBirthday })
</script>

<template>
  <div class="base-input-birthday">
    <div :class="[layout]">
      <label>{{ props?.label }} <span v-if="must">*</span></label>
      <div class="input-wrap">
        <!-- 日 -->
        <input
          ref="dayInputRef" v-model="day" type="number" :max="dayMax" autocomplete="on"
          :placeholder="$t('reg_day')" @input="onInput"
        >
        <!-- 月 -->
        <div class="select-wrap">
            <BaseButton type="none" class="w-full border rounded-[4px] border-[#3B4041] bg-[#1E2121] text-[0.75rem] !p-0" @click.stop="isPop = true">
              <div class="flex w-full pl-3 pr-2 ">
                
                <div v-if="month < 1" class="mr-auto text-[#B3BEC1]">Month</div>
                <div v-else class="mr-auto">{{ $t(`${monthList.filter(item=>item.value == month)[0].label}`) }}</div>
                <BaseIcon name="uni-arrow-down" class="pl-1" />
              </div>
            </BaseButton>
        </div>
        <!-- 年 -->
        <input
          ref="yearInputRef" v-model="year" type="number"
          :placeholder="$t('time_year')" @input="onInput"
        >
      </div>
    </div>
    <BaseBob v-model:show="isPop" :header="$t('choice_time')" :option="setAreaList" v-model:selected="month" />

  </div>
</template>
<style scoped lang="scss">
.base-input-birthday{
    .input-wrap {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 8px;

    input,
    select {
      width: 100%;
      border-radius: 4px;
      background: #1E2121;
      border-width: 1px;
      border-style: solid;
      border-color: #3B4041;
      color: #fff;
      outline: none;
      transition: all ease .25s;
      line-height: 1;
      font-weight: 600;
      padding-left: 0.75rem;
      padding-right: 0.5rem;

      &:focus:not(.error) {
        border-color: #24EE89
      }

      &::placeholder {
        font-weight: 600;
        color: #B3BEC1;
      }
    }
  }
}
</style>